/*
Xern Entity Relocation Network
Copyright (C) 2011 Ronie Salgado <roniesalg@gmail.com>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#ifndef XTOOL_MAPDATA_H
#define XTOOL_MAPDATA_H

#include <vector>
#include <map>
#include <boost/shared_ptr.hpp>
#include <boost/uuid/uuid.hpp>
#include "Xern/Color.hpp"
#include "Xern/Vector.hpp"
#include "Xern/Transform.hpp"
#include "Xern/Plane.hpp"

namespace MapXern
{
	using boost::uuids::uuid;
    using namespace Xern;

    class BrushFace
    {
    public:
        BrushFace();
        ~BrushFace();

        void AddVertex(const Vector3 &vertex);

        Plane plane;

        typedef std::vector<Vector3> Vertices;
        Vertices vertices;

        typedef std::vector<Vector2> Texcoords;
        Texcoords texcoords;

        typedef std::vector<Vector3> Tangents;
        Tangents tangents;

        typedef std::vector<Vector3> BiTangents;
        BiTangents bitangents;

        typedef std::vector<int> Indices;
        Indices indices;

        Vector2 mapOffset, mapScale;
        float mapRot;
        float globalScale;
        Vector2 textureSize;
        std::string textureName;
    };

    class Brush
    {
    public:
        Brush();
        ~Brush();

        typedef std::vector<BrushFace> Faces;
        Faces faces;

        Vector3 center;

        uuid id;

        // This is temporal.
        Transform localTransform;
    };

    class Entity
    {
    public:
        Entity();
        ~Entity();

        std::string className;

        typedef std::map<std::string, std::string> Properties;
        Properties properties;
    };

    class Object
    {
    public:
        Object();
        ~Object();

        template<typename FUNCTOR>
        void Traverse(FUNCTOR f)
        {
            // Don't care about the root object.
            Children::iterator it = children.begin();
            for(; it != children.end(); it++)
            {
                boost::shared_ptr<Object> child = *it;
                f(child);

                // Traverse the child.
                child->Traverse(f);
            }
        }

        std::string name;
        uuid id;
        Transform transform;

        boost::shared_ptr<Brush> brush;
        boost::shared_ptr<Entity> entity;

        typedef std::vector<boost::shared_ptr<Object> > Children;
        Children children;
    };

}; // namespace XernMap

#endif //XTOOL_MAPDATA_H
